package vn.personal.anhht.bloback12.widget;

import java.util.ArrayList;
import java.util.List;

import vn.personal.anhht.bloback12.activity.R;
import android.content.Context;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.view.animation.Interpolator;
import android.widget.ImageView;
import android.widget.PopupWindow.OnDismissListener;
import android.widget.TextView;

/**
 * QuickAction dialog.
 * 
 * @author Lorensius W. L. T <lorenz@londatiga.net>
 * 
 *         Contributors: - Kevin Peck <kevinwpeck@gmail.com>
 */
public class QuickAction extends PopupWindows implements OnDismissListener {
    private ImageView mArrowUp;
    private ImageView mArrowDown;
    private Animation mTrackAnim;
    private LayoutInflater inflater;
    private ViewGroup mTrack;
    private OnActionItemClickListener mItemClickListener;
    private OnDismissListener mDismissListener;

    private List<ActionItem> mActionItemList = new ArrayList<ActionItem>();

    private boolean mDidAction;
    private boolean mAnimateTrack;

    private int mChildPos;
    private int mAnimStyle;

    public static final int ANIM_GROW_FROM_LEFT = 1;
    public static final int ANIM_GROW_FROM_RIGHT = 2;
    public static final int ANIM_GROW_FROM_CENTER = 3;
    public static final int ANIM_AUTO = 4;

    /**
     * Constructor.
     * 
     * @param context
     *            Context
     */
    public QuickAction(Context context) {
        super(context);

        inflater = (LayoutInflater) context
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);

        mTrackAnim = AnimationUtils.loadAnimation(context, R.anim.rail);

        mTrackAnim.setInterpolator(new Interpolator() {
            public float getInterpolation(float t) {
                // Pushes past the target area, then snaps back into place.
                // Equation for graphing: 1.2-((x*1.6)-1.1)^2
                final float inner = (t * 1.55f) - 1.1f;

                return 1.2f - inner * inner;
            }
        });

        setRootViewId(R.layout.quickaction);

        mAnimStyle = ANIM_AUTO;
        mAnimateTrack = true;
        mChildPos = 0;
    }

    /**
     * Get action item at an index
     * 
     * @param index
     *            Index of item (position from callback)
     * 
     * @return Action Item at the position
     */
    public ActionItem getActionItem(int index) {
        return mActionItemList.get(index);
    }

    /**
     * Set root view.
     * 
     * @param id
     *            Layout resource id
     */
    public void setRootViewId(int id) {
        mRootView = (ViewGroup) inflater.inflate(id, null);
        mTrack = (ViewGroup) mRootView.findViewById(R.id.tracks);

        mArrowDown = (ImageView) mRootView.findViewById(R.id.arrow_down);
        mArrowUp = (ImageView) mRootView.findViewById(R.id.arrow_up);

        // This was previously defined on show() method, moved here to prevent
        // force close that occured
        // when tapping fastly on a view to show quickaction dialog.
        // Thanx to zammbi (github.com/zammbi)
        mRootView.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT,
                LayoutParams.WRAP_CONTENT));

        setContentView(mRootView);
    }

    /**
     * Animate track.
     * 
     * @param mAnimateTrack
     *            flag to animate track
     */
    public void mAnimateTrack(boolean mAnimateTrack) {
        this.mAnimateTrack = mAnimateTrack;
    }

    /**
     * Set animation style.
     * 
     * @param mAnimStyle
     *            animation style, default is set to ANIM_AUTO
     */
    public void setAnimStyle(int mAnimStyle) {
        this.mAnimStyle = mAnimStyle;
    }

    /**
     * Add action item
     * 
     * @param action
     *            {@link ActionItem}
     */
    public void addActionItem(ActionItem action) {

        String title = action.getTitle();
        Drawable icon = action.getIcon();

        View container = (View) inflater.inflate(R.layout.action_item, null);

        ImageView img = (ImageView) container.findViewById(R.id.iv_icon);
        TextView text = (TextView) container.findViewById(R.id.tv_title);

        if (icon != null) {
            img.setImageDrawable(icon);
        } else {
            img.setVisibility(View.GONE);
        }

        if (title != null) {
            text.setText(title);
        } else {
            text.setVisibility(View.GONE);
        }

        if (icon == null && title == null) {
            mActionItemList.add(action);
        } else {
            mActionItemList.add(action);
            final int pos = mChildPos;
            final int actionId = action.getActionId();

            container.setOnClickListener(new OnClickListener() {
                @Override
                public void onClick(View v) {
                    if (mItemClickListener != null) {
                        mItemClickListener.onItemClick(QuickAction.this, pos,
                                actionId);
                    }

                    if (!getActionItem(pos).isSticky()) {
                        mDidAction = true;

                        // workaround for transparent background bug
                        // thx to Roman Wozniak <roman.wozniak@gmail.com>
                        v.post(new Runnable() {
                            @Override
                            public void run() {
                                // dismiss();
                            }
                        });
                    }
                }
            });

            container.setFocusable(true);
            container.setClickable(true);

            mTrack.addView(container, mChildPos + 1);

            mChildPos++;
            
        }

    }
    
    public void replaceActionItem(int position, ActionItem action){
        mTrack.removeViewAt(position+1);
        mActionItemList.remove(position);
        
        String title = action.getTitle();
        Drawable icon = action.getIcon();

        View container = (View) inflater.inflate(R.layout.action_item, null);

        ImageView img = (ImageView) container.findViewById(R.id.iv_icon);
        TextView text = (TextView) container.findViewById(R.id.tv_title);

        if (icon != null) {
            img.setImageDrawable(icon);
        } else {
            img.setVisibility(View.GONE);
        }

        if (title != null) {
            text.setText(title);
        } else {
            text.setVisibility(View.GONE);
        }

        if (icon == null && title == null) {
            //mActionItemList.add(action);
            mActionItemList.add(position, action);
        } else {
//            mActionItemList.add(action);
            mActionItemList.add(position, action);
            //final int pos = mChildPos;
            final int pos = position;
            final int actionId = action.getActionId();

            container.setOnClickListener(new OnClickListener() {
                @Override
                public void onClick(View v) {
                    
                        // workaround for transparent background bug
                        // thx to Roman Wozniak <roman.wozniak@gmail.com>
                        v.post(new Runnable() {
                            @Override
                            public void run() {
                                // dismiss();
                                if (mItemClickListener != null) {
                                    mItemClickListener.onItemClick(QuickAction.this, pos, actionId);
                                }

                                if (!getActionItem(pos).isSticky()) {
                                    mDidAction = true;
                                }
                            }
                        });
                    
                }
            });

            container.setFocusable(true);
            container.setClickable(true);

            mTrack.addView(container, position + 1);
            
            mChildPos++;
            
        }
    }

    public void setOnActionItemClickListener(OnActionItemClickListener listener) {
        mItemClickListener = listener;
    }

    /**
     * Show popup mWindow
     */
    public void show(View anchor) {
        preShow();

        int[] location = new int[2];

        mDidAction = false;

        anchor.getLocationOnScreen(location);

        Rect anchorRect = new Rect(location[0], location[1], location[0]
                + anchor.getWidth(), location[1] + anchor.getHeight());

        // mRootView.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT,
        // LayoutParams.WRAP_CONTENT));
        mRootView.measure(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);

        int rootWidth = mRootView.getMeasuredWidth();
        int rootHeight = mRootView.getMeasuredHeight();

        int screenWidth = mWindowManager.getDefaultDisplay().getWidth();
        // int screenHeight = mWindowManager.getDefaultDisplay().getHeight();

        int xPos = (screenWidth - rootWidth) / 2;
        int yPos = anchorRect.top - rootHeight;

        boolean onTop = true;

        // display on bottom
        if (rootHeight > anchor.getTop()) {
            yPos = anchorRect.bottom;
            onTop = false;
        }

        showArrow(((onTop) ? R.id.arrow_down : R.id.arrow_up),
                anchorRect.centerX());

        setAnimationStyle(screenWidth, anchorRect.centerX(), onTop);

        mWindow.showAtLocation(anchor, Gravity.NO_GRAVITY, xPos, yPos);

        if (mAnimateTrack)
            mTrack.startAnimation(mTrackAnim);
    }

    /**
     * Set animation style
     * 
     * @param screenWidth
     *            Screen width
     * @param requestedX
     *            distance from left screen
     * @param onTop
     *            flag to indicate where the popup should be displayed. Set TRUE
     *            if displayed on top of anchor and vice versa
     */
    private void setAnimationStyle(int screenWidth, int requestedX,
            boolean onTop) {
        int arrowPos = requestedX - mArrowUp.getMeasuredWidth() / 2;

        switch (mAnimStyle) {
        case ANIM_GROW_FROM_LEFT:
            mWindow.setAnimationStyle((onTop) ? R.style.Animations_PopUpMenu_Left
                    : R.style.Animations_PopDownMenu_Left);
            break;

        case ANIM_GROW_FROM_RIGHT:
            mWindow.setAnimationStyle((onTop) ? R.style.Animations_PopUpMenu_Right
                    : R.style.Animations_PopDownMenu_Right);
            break;

        case ANIM_GROW_FROM_CENTER:
            mWindow.setAnimationStyle((onTop) ? R.style.Animations_PopUpMenu_Center
                    : R.style.Animations_PopDownMenu_Center);
            break;

        case ANIM_AUTO:
            if (arrowPos <= screenWidth / 4) {
                mWindow.setAnimationStyle((onTop) ? R.style.Animations_PopUpMenu_Left
                        : R.style.Animations_PopDownMenu_Left);
            } else if (arrowPos > screenWidth / 4
                    && arrowPos < 3 * (screenWidth / 4)) {
                mWindow.setAnimationStyle((onTop) ? R.style.Animations_PopUpMenu_Center
                        : R.style.Animations_PopDownMenu_Center);
            } else {
                mWindow.setAnimationStyle((onTop) ? R.style.Animations_PopDownMenu_Right
                        : R.style.Animations_PopDownMenu_Right);
            }

            break;
        }
    }

    /**
     * Show arrow
     * 
     * @param whichArrow
     *            arrow type resource id
     * @param requestedX
     *            distance from left screen
     */
    private void showArrow(int whichArrow, int requestedX) {
        final View showArrow = (whichArrow == R.id.arrow_up) ? mArrowUp
                : mArrowDown;
        final View hideArrow = (whichArrow == R.id.arrow_up) ? mArrowDown
                : mArrowUp;

        final int arrowWidth = mArrowUp.getMeasuredWidth();

        showArrow.setVisibility(View.VISIBLE);

        ViewGroup.MarginLayoutParams param = (ViewGroup.MarginLayoutParams) showArrow
                .getLayoutParams();

        param.leftMargin = requestedX - arrowWidth / 2;

        hideArrow.setVisibility(View.INVISIBLE);
    }

    /**
     * Set listener for window dismissed. This listener will only be fired if
     * the quicakction dialog is dismissed by clicking outside the dialog or
     * clicking on sticky item.
     */
    public void setOnDismissListener(QuickAction.OnDismissListener listener) {
        setOnDismissListener(this);

        mDismissListener = listener;
    }

    @Override
    public void onDismiss() {
        if (!mDidAction && mDismissListener != null) {
            mDismissListener.onDismiss();
        }
    }

    /**
     * Listener for item click
     * 
     */
    public interface OnActionItemClickListener {
        public abstract void onItemClick(QuickAction source, int pos,
                int actionId);
    }

    /**
     * Listener for window dismiss
     * 
     */
    public interface OnDismissListener {
        public abstract void onDismiss();
    }
}